/** @format */

import React from 'react';
import {admin as adminApi} from '@/api/admin';
import {setting} from './index.styl';
import CodeFlask from 'codeflask';
import Button from '@material-ui/core/Button';
import SaveIcon from '@material-ui/icons/Save';
import Edit from '@material-ui/icons/Edit';
import Cancel from '@material-ui/icons/Cancel';
import AlertDialog from '@/view/admin/component/dialog';
import DeleteIcon from '@material-ui/icons/Delete';

// 提示框
interface IAlertDialog {
  open: boolean;
  // 默认 top
  vertical?: 'top' | 'bottom';
  // 默认 center
  horizontal?: 'left' | 'center' | 'right';
  // 默认 ''
  msg: string;
  // 默认 info
  severity?: 'error' | 'warning' | 'info' | 'success';
  // 多少秒后消失
  autoHideDuration?: number;
}

// 配置
interface IConfig {
  isEdit: boolean;
  newConfig: string;
  config: string;
}

// 用户列表
interface IUser {
  id: number;
  user: string;
  pwd: string;
  // 保存编辑过程中的user
  newPwd: string;
  // 显示编辑 取消按钮
  isEdit: boolean;
}

// 新增用户
interface IAddNewUser {
  user: string;
  pwd: string;
  // 显示新增 取消按钮
  isEdit: boolean;
}

interface IProps {
  [propName: string]: any;
}

interface IState {
  config: IConfig;
  userList: IUser[] | [];
  addNewUser: IAddNewUser;
  alertDialog: IAlertDialog;
}

class Setting extends React.Component<IProps, IState> {
  private flask: any = '123';
  constructor(props: IProps) {
    super(props);
    this.componentDidMount = this.componentDidMount.bind(this);
    this.componentWillUnmount = this.componentWillUnmount.bind(this);
    this.alertDialogClose = this.alertDialogClose.bind(this);
    this.getConfig = this.getConfig.bind(this);
    this.getUserList = this.getUserList.bind(this);
    this.userList = this.userList.bind(this);
    this.editorUserOperate = this.editorUserOperate.bind(this);
    this.editorConfigOperate = this.editorConfigOperate.bind(this);
    this.submitUserPwd = this.submitUserPwd.bind(this);
    this.deleteUser = this.deleteUser.bind(this);
    this.submitUserPwd = this.submitUserPwd.bind(this);
    this.state = {
      config: {
        isEdit: false,
        config: '',
        newConfig: '',
      },
      userList: [],
      addNewUser: {
        user: '',
        pwd: '',
        // 显示新增 取消按钮
        isEdit: false,
      },
      alertDialog: {
        msg: '',
        open: false,
      },
    };
  }

  // 初始化 CodeFlask
  componentDidMount() {
    this.flask = new CodeFlask('#editor', {
      language: 'js',
    });

    this.flask.onUpdate((code: string) => {
      this.setState({config: {...this.state.config, newConfig: code}});
    });
    this.getConfig();
    this.getUserList();
  }

  // 移除相关函数
  componentWillUnmount() {
    this.flask = null;
  }

  alertDialogClose() {
    this.setState({
      alertDialog: {
        ...this.state.alertDialog,
        open: false,
      },
    });
  }

  async getConfig() {
    const [resErr, config]: any = await adminApi.getConfig();
    if (resErr) {
      this.setState({
        alertDialog: {
          ...this.state.alertDialog,
          open: true,
          msg: resErr.msg,
          severity: 'error',
        },
      });
    } else {
      this.setState({
        config: {
          ...this.state.config,
          config: config.configData,
        },
      });
      this.flask.updateCode(config.configData);
    }
  }

  // 修改配置操作
  editorConfigOperate(operate: 'editor' | 'cancel' | 'save') {
    const config = this.state.config;
    config.isEdit = operate === 'editor';
    this.setState({config});
    // 不保存
    if (operate === 'cancel') {
      this.flask.updateCode(this.state.config.config);
    }

    if (operate === 'save') {
      this.submitConfig();
    }
  }

  // 提交新配置
  async submitConfig() {
    const [submitConfig, rsp]: any = await adminApi.postConfig({config: this.state.config.newConfig});
    // 更新失败
    if (submitConfig) {
      this.setState({
        alertDialog: {
          ...this.state.alertDialog,
          open: true,
          msg: submitConfig.msg,
          severity: 'error',
        },
      });
    } else {
      this.setState({
        alertDialog: {
          ...this.state.alertDialog,
          open: true,
          msg: rsp.msg,
          severity: 'success',
        },
      });
    }
    this.getConfig();
  }

  async getUserList() {
    const [userListErr, userList]: any = await adminApi.getUserList();
    if (userListErr) {
      this.setState({
        alertDialog: {
          ...this.state.alertDialog,
          open: true,
          msg: userListErr.msg,
          severity: 'error',
        },
      });
    } else {
      const newList = userList.userList.map((item: {user: string; id: number}) => {
        return {
          ...item,
          pwd: '******',
          newPwd: '******',
          isEdit: false,
        };
      });
      this.setState({userList: newList});
    }
  }
  // 用户列表
  userList(users: IUser[]) {
    const list = users.map((item: IUser, index: number) => {
      return (
        <div key={index}>
          <span>{item.user}</span>
          <input
            type="password"
            value={this.state.userList[index].newPwd}
            disabled={!item.isEdit}
            onChange={e => {
              this.pwdInputHandle(e, index);
            }}
          />
          <Button
            variant="contained"
            color="primary"
            startIcon={<Edit />}
            onClick={() => this.editorUserOperate('editor', index)}
            className={`${item.isEdit ? 'hide' : ''}`}>
            编辑
          </Button>
          <Button
            variant="contained"
            color="primary"
            startIcon={<DeleteIcon />}
            onClick={() => this.editorUserOperate('del', index)}
            className={`${item.isEdit ? 'hide' : ''}`}>
            删除
          </Button>
          <Button
            variant="contained"
            color="secondary"
            startIcon={<Cancel />}
            onClick={() => this.editorUserOperate('save', index)}
            className={`${!item.isEdit ? 'hide' : ''}`}>
            保存
          </Button>
          <Button
            variant="contained"
            color="secondary"
            startIcon={<Cancel />}
            onClick={() => this.editorUserOperate('cancel', index)}
            className={`${!item.isEdit ? 'hide' : ''}`}>
            取消
          </Button>
        </div>
      );
    });
    return <div className={`user-list-wrap`}>{list}</div>;
  }

  // 用户列表操作
  editorUserOperate(operate: 'editor' | 'cancel' | 'save' | 'del', i: number) {
    const userList = this.state.userList;
    // 更新显示状态
    if (operate === 'editor') {
      userList[i].isEdit = true;
      this.setState({userList});
      return;
    }

    // 取消
    if (operate === 'cancel') {
      userList[i].isEdit = false;
      userList[i].newPwd = '******';
      this.setState({userList});
      return;
    }

    if (operate === 'save') {
      this.submitUserPwd(i);
      return;
    }

    if (operate === 'del') {
      this.deleteUser(i);
    }
  }

  // 更新用户密码
  async submitUserPwd(i: number) {
    const selecteUser = this.state.userList[i];
    const params = {
      user: selecteUser.user,
      newPwd: selecteUser.newPwd,
    };
    if (params.newPwd.length < 6) {
      this.flask.updateCode(this.state.config);
      this.setState({
        alertDialog: {
          ...this.state.alertDialog,
          open: true,
          msg: '密码长度不少于6位 更新失败',
          severity: 'warning',
        },
      });
    }
    const [submitUserPwd, rsp]: any = await adminApi.postPwd(params);
    // 更新失败
    if (submitUserPwd) {
      this.setState({
        alertDialog: {
          ...this.state.alertDialog,
          open: true,
          msg: submitUserPwd.msg,
          severity: 'error',
        },
      });
    } else {
      this.setState({
        alertDialog: {
          ...this.state.alertDialog,
          open: true,
          msg: rsp.msg,
          severity: 'success',
        },
      });
    }
    this.getUserList();
  }

  // 删除用户
  async deleteUser(i: number) {
    const selecteUser = this.state.userList[i];
    const params = {
      user: selecteUser.user,
    };

    const [deleteUserErr, rsp]: any = await adminApi.deleteUser(params);
    // 更新失败
    if (deleteUserErr) {
      this.setState({
        alertDialog: {
          ...this.state.alertDialog,
          open: true,
          msg: deleteUserErr.msg,
          severity: 'error',
        },
      });
    } else {
      this.setState({
        alertDialog: {
          ...this.state.alertDialog,
          open: true,
          msg: rsp.msg,
          severity: 'success',
        },
      });
    }
    this.getUserList();
  }

  // 用户列表输入新密码
  pwdInputHandle(e: React.ChangeEvent<HTMLInputElement>, index: number) {
    const val = e.target.value;
    const userList = this.state.userList;
    userList[index].newPwd = val;
    this.setState({
      ...this.state,
      userList,
    });
  }

  // 增加用户
  addUser() {
    return (
      <div className={`add-user-wrap`}>
        <div className={`input-wrap`}>
          <input
            type="text"
            value={this.state.addNewUser.user}
            onChange={e => {
              this.addUserInputHandle(e, 'user');
            }}
            className={`${!this.state.addNewUser.isEdit ? 'hide' : ''} user-input`}
          />
          <input
            type="text"
            value={this.state.addNewUser.pwd}
            onChange={e => {
              this.addUserInputHandle(e, 'pwd');
            }}
            className={`${!this.state.addNewUser.isEdit ? 'hide' : ''}`}
          />
        </div>
        <div className={`add-user-operation`}>
          <Button
            variant="contained"
            color="primary"
            startIcon={<Edit />}
            onClick={() => this.addUserOperate('add')}
            className={`${this.state.addNewUser.isEdit ? 'hide' : ''} add-btn`}>
            增加
          </Button>
          <Button
            variant="contained"
            color="secondary"
            startIcon={<Cancel />}
            onClick={() => this.addUserOperate('save')}
            className={`${!this.state.addNewUser.isEdit ? 'hide' : ''}`}>
            保存
          </Button>
          <Button
            variant="contained"
            color="secondary"
            startIcon={<Cancel />}
            onClick={() => this.addUserOperate('cancel')}
            className={`${!this.state.addNewUser.isEdit ? 'hide' : ''}`}>
            取消
          </Button>
        </div>
      </div>
    );
  }

  addUserInputHandle(e: React.ChangeEvent<HTMLInputElement>, valType: 'user' | 'pwd') {
    const val = e.target.value;
    valType === 'user'
      ? this.setState({addNewUser: {...this.state.addNewUser, user: val}})
      : this.setState({addNewUser: {...this.state.addNewUser, pwd: val}});
  }

  async addUserOperate(operation: 'save' | 'cancel' | 'add') {
    if (operation === 'save') {
      const params = {
        user: this.state.addNewUser.user,
        pwd: this.state.addNewUser.pwd,
      };
      if (!params.user.length) {
        this.setState({
          alertDialog: {
            ...this.state.alertDialog,
            open: true,
            msg: '请填写用户名',
            severity: 'warning',
          },
        });
        return;
      }
      if (params.pwd.length < 6) {
        this.setState({
          alertDialog: {
            ...this.state.alertDialog,
            open: true,
            msg: '密码长度不能小于6位',
            severity: 'warning',
          },
        });
        return;
      }

      const [addUserRspErr, addUserRsp]: any = await adminApi.addUser(params);
      if (addUserRspErr) {
        this.setState({
          alertDialog: {
            ...this.state.alertDialog,
            open: true,
            msg: addUserRspErr.msg,
            severity: 'error',
          },
        });
      }

      this.setState({
        alertDialog: {
          ...this.state.alertDialog,
          open: true,
          msg: addUserRsp.msg,
          severity: 'success',
        },
      });

      // 更新用户列表
      this.getUserList();
    }
    const addNewUser: IAddNewUser = {
      user: '',
      pwd: '',
      isEdit: operation === 'add',
    };
    this.setState({addNewUser});
  }

  render(): JSX.Element {
    return (
      <div className={setting}>
        <div className={`general-setting`}>
          <h2>通用配置</h2>
          <div id="editor" className={`${this.state.config.isEdit ? 'editor' : 'read'}`}></div>
          <Button
            variant="contained"
            color="primary"
            startIcon={<Edit />}
            onClick={() => this.editorConfigOperate('editor')}
            className={`${this.state.config.isEdit ? 'hide' : ''}`}>
            编辑
          </Button>
          <Button
            variant="contained"
            color="primary"
            startIcon={<SaveIcon />}
            onClick={() => this.editorConfigOperate('save')}
            className={`${this.state.config.isEdit ? '' : 'hide'}`}>
            保存
          </Button>
          <Button
            variant="contained"
            color="secondary"
            startIcon={<Cancel />}
            onClick={() => this.editorConfigOperate('cancel')}
            className={`${this.state.config.isEdit ? '' : 'hide'}`}>
            取消
          </Button>
        </div>
        <div className={`account-setting`}>
          <h2>账号管理</h2>
          {this.userList(this.state.userList)}
          {this.addUser()}
        </div>
        <AlertDialog {...this.state.alertDialog} onClose={this.alertDialogClose} />
      </div>
    );
  }
}

export default Setting;
